Merge "Remove wfRandomString() dependency in DatabaseBase"
[lhc/web/wiklou.git] / includes / db / Database.php
index 109dbfe..5d1078a 100644 (file)
@@ -60,6 +60,8 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
        protected $mPassword;
        /** @var string */
        protected $mDBname;
+       /** @var array[] $aliases Map of (table => (dbname, schema, prefix) map) */
+       protected $tableAliases = [];
        /** @var bool */
        protected $cliMode;
 
@@ -69,6 +71,8 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
        protected $connLogger;
        /** @var LoggerInterface */
        protected $queryLogger;
+       /** @var callback Error logging callback */
+       protected $errorLogger;
 
        /** @var resource Database connection */
        protected $mConn = null;
@@ -81,7 +85,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
        protected $mTrxPreCommitCallbacks = [];
        /** @var array[] List of (callable, method name) */
        protected $mTrxEndCallbacks = [];
-       /** @var array[] Map of (name => (callable, method name)) */
+       /** @var callable[] Map of (name => callable) */
        protected $mTrxRecurringCallbacks = [];
        /** @var bool Whether to suppress triggering of transaction end callbacks */
        protected $mTrxEndCallbacksSuppressed = false;
@@ -92,8 +96,6 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
        protected $mSchema;
        /** @var integer */
        protected $mFlags;
-       /** @var bool */
-       protected $mForeign;
        /** @var array */
        protected $mLBInfo = [];
        /** @var bool|null */
@@ -231,24 +233,20 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
         * connection object, by specifying no parameters to __construct(). This
         * feature is deprecated and should be removed.
         *
-        * DatabaseBase subclasses should not be constructed directly in external
+        * IDatabase classes should not be constructed directly in external
         * code. DatabaseBase::factory() should be used instead.
         *
         * @param array $params Parameters passed from DatabaseBase::factory()
         */
        function __construct( array $params ) {
-               global $wgDBprefix, $wgDBmwschema;
-
-               $this->srvCache = ObjectCache::getLocalServerInstance( 'hash' );
-
                $server = $params['host'];
                $user = $params['user'];
                $password = $params['password'];
                $dbName = $params['dbname'];
                $flags = $params['flags'];
-               $tablePrefix = $params['tablePrefix'];
-               $schema = $params['schema'];
-               $foreign = $params['foreign'];
+
+               $this->mSchema = $params['schema'];
+               $this->mTablePrefix = $params['tablePrefix'];
 
                $this->cliMode = isset( $params['cliMode'] )
                        ? $params['cliMode']
@@ -265,21 +263,9 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
 
                $this->mSessionVars = $params['variables'];
 
-               /** Get the default table prefix*/
-               if ( $tablePrefix === 'get from global' ) {
-                       $this->mTablePrefix = $wgDBprefix;
-               } else {
-                       $this->mTablePrefix = $tablePrefix;
-               }
-
-               /** Get the database schema*/
-               if ( $schema === 'get from global' ) {
-                       $this->mSchema = $wgDBmwschema;
-               } else {
-                       $this->mSchema = $schema;
-               }
-
-               $this->mForeign = $foreign;
+               $this->srvCache = isset( $params['srvCache'] )
+                       ? $params['srvCache']
+                       : new HashBagOStuff();
 
                $this->profiler = isset( $params['profiler'] )
                        ? $params['profiler']
@@ -301,7 +287,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
 
        /**
         * Given a DB type, construct the name of the appropriate child class of
-        * DatabaseBase. This is designed to replace all of the manual stuff like:
+        * IDatabase. This is designed to replace all of the manual stuff like:
         *    $class = 'Database' . ucfirst( strtolower( $dbType ) );
         * as well as validate against the canonical list of DB types we have
         *
@@ -318,8 +304,8 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
         * @param string $dbType A possible DB type
         * @param array $p An array of options to pass to the constructor.
         *    Valid options are: host, user, password, dbname, flags, tablePrefix, schema, driver
-        * @throws MWException If the database driver or extension cannot be found
-        * @return DatabaseBase|null DatabaseBase subclass or null
+        * @return IDatabase|null If the database driver or extension cannot be found
+        * @throws InvalidArgumentException If the database driver or extension cannot be found
         */
        final public static function factory( $dbType, $p = [] ) {
                global $wgCommandLineMode;
@@ -355,7 +341,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                        $driver = $dbType;
                }
                if ( $driver === false ) {
-                       throw new MWException( __METHOD__ .
+                       throw new InvalidArgumentException( __METHOD__ .
                                " no viable database extension found for type '$dbType'" );
                }
 
@@ -368,7 +354,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                ];
 
                $class = 'Database' . ucfirst( $driver );
-               if ( class_exists( $class ) && is_subclass_of( $class, 'DatabaseBase' ) ) {
+               if ( class_exists( $class ) && is_subclass_of( $class, 'IDatabase' ) ) {
                        // Resolve some defaults for b/c
                        $p['host'] = isset( $p['host'] ) ? $p['host'] : false;
                        $p['user'] = isset( $p['user'] ) ? $p['user'] : false;
@@ -376,7 +362,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                        $p['dbname'] = isset( $p['dbname'] ) ? $p['dbname'] : false;
                        $p['flags'] = isset( $p['flags'] ) ? $p['flags'] : 0;
                        $p['variables'] = isset( $p['variables'] ) ? $p['variables'] : [];
-                       $p['tablePrefix'] = isset( $p['tablePrefix'] ) ? $p['tablePrefix'] : 'get from global';
+                       $p['tablePrefix'] = isset( $p['tablePrefix'] ) ? $p['tablePrefix'] : '';
                        if ( !isset( $p['schema'] ) ) {
                                $p['schema'] = isset( $defaultSchemas[$dbType] ) ? $defaultSchemas[$dbType] : null;
                        }
@@ -390,6 +376,11 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                        if ( isset( $p['queryLogger'] ) ) {
                                $conn->queryLogger = $p['queryLogger'];
                        }
+                       if ( isset( $p['errorLogger'] ) ) {
+                               $conn->errorLogger = $p['errorLogger'];
+                       } else {
+                               $conn->errorLogger = [ MWExceptionHandler::class, 'logException' ];
+                       }
                } else {
                        $conn = null;
                }
@@ -398,7 +389,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
        }
 
        public function setLogger( LoggerInterface $logger ) {
-               $this->quertLogger = $logger;
+               $this->queryLogger = $logger;
        }
 
        public function getServerInfo() {
@@ -494,12 +485,6 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                }
        }
 
-       /**
-        * Set a lazy-connecting DB handle to the master DB (for replication status purposes)
-        *
-        * @param IDatabase $conn
-        * @since 1.27
-        */
        public function setLazyMasterHandle( IDatabase $conn ) {
                $this->lazyMasterHandle = $conn;
        }
@@ -680,43 +665,6 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                }
        }
 
-       /**
-        * Return a path to the DBMS-specific SQL file if it exists,
-        * otherwise default SQL file
-        *
-        * @param string $filename
-        * @return string
-        */
-       private function getSqlFilePath( $filename ) {
-               global $IP;
-               $dbmsSpecificFilePath = "$IP/maintenance/" . $this->getType() . "/$filename";
-               if ( file_exists( $dbmsSpecificFilePath ) ) {
-                       return $dbmsSpecificFilePath;
-               } else {
-                       return "$IP/maintenance/$filename";
-               }
-       }
-
-       /**
-        * Return a path to the DBMS-specific schema file,
-        * otherwise default to tables.sql
-        *
-        * @return string
-        */
-       public function getSchemaPath() {
-               return $this->getSqlFilePath( 'tables.sql' );
-       }
-
-       /**
-        * Return a path to the DBMS-specific update key file,
-        * otherwise default to update-keys.sql
-        *
-        * @return string
-        */
-       public function getUpdateKeysPath() {
-               return $this->getSqlFilePath( 'update-keys.sql' );
-       }
-
        /**
         * Get information about an index into an object
         * @param string $table Table name
@@ -747,7 +695,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
        protected function installErrorHandler() {
                $this->mPHPError = false;
                $this->htmlErrors = ini_set( 'html_errors', '0' );
-               set_error_handler( [ $this, 'connectionErrorHandler' ] );
+               set_error_handler( [ $this, 'connectionerrorLogger' ] );
        }
 
        /**
@@ -772,12 +720,12 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
         * @param int $errno
         * @param string $errstr
         */
-       public function connectionErrorHandler( $errno, $errstr ) {
+       public function connectionerrorLogger( $errno, $errstr ) {
                $this->mPHPError = $errstr;
        }
 
        /**
-        * Create a log context to pass to wfLogDBError or other logging functions.
+        * Create a log context to pass to PSR logging functions.
         *
         * @param array $extras Additional data to add to context
         * @return array
@@ -796,11 +744,6 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
        public function close() {
                if ( $this->mConn ) {
                        if ( $this->trxLevel() ) {
-                               if ( !$this->mTrxAutomatic ) {
-                                       wfWarn( "Transaction still in progress (from {$this->mTrxFname}), " .
-                                               " performing implicit commit before closing connection!" );
-                               }
-
                                $this->commit( __METHOD__, self::FLUSHING_INTERNAL );
                        }
 
@@ -954,7 +897,8 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                        if ( $this->reconnect() ) {
                                $msg = __METHOD__ . ": lost connection to {$this->getServer()}; reconnected";
                                $this->connLogger->warning( $msg );
-                               $this->queryLogger->warning( "$msg:\n" . wfBacktrace( true ) );
+                               $this->queryLogger->warning(
+                                       "$msg:\n" . ( new RuntimeException() )->getTraceAsString() );
 
                                if ( !$recoverable ) {
                                        # Callers may catch the exception and continue to use the DB
@@ -995,9 +939,9 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                # generalizeSQL() will probably cut down the query to reasonable
                # logging size most of the time. The substr is really just a sanity check.
                if ( $isMaster ) {
-                       $queryProf = 'query-m: ' . substr( DatabaseBase::generalizeSQL( $sql ), 0, 255 );
+                       $queryProf = 'query-m: ' . substr( self::generalizeSQL( $sql ), 0, 255 );
                } else {
-                       $queryProf = 'query: ' . substr( DatabaseBase::generalizeSQL( $sql ), 0, 255 );
+                       $queryProf = 'query: ' . substr( self::generalizeSQL( $sql ), 0, 255 );
                }
 
                # Include query transaction state
@@ -1103,7 +1047,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                        $this->queryLogger->debug( "SQL ERROR (ignored): $error\n" );
                } else {
                        $sql1line = mb_substr( str_replace( "\n", "\\n", $sql ), 0, 5 * 1024 );
-                       wfLogDBError(
+                       $this->queryLogger->error(
                                "{fname}\t{db_server}\t{errno}\t{error}\t{sql1line}",
                                $this->getLogContext( [
                                        'method' => __METHOD__,
@@ -1132,7 +1076,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
         *
         * @return array
         */
-       protected function prepare( $sql, $func = 'DatabaseBase::prepare' ) {
+       protected function prepare( $sql, $func = __METHOD__ ) {
                /* MySQL doesn't support prepared statements (yet), so just
                 * pack up the query for reference. We'll manually replace
                 * the bits later.
@@ -1705,7 +1649,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
 
        public function makeList( $a, $mode = LIST_COMMA ) {
                if ( !is_array( $a ) ) {
-                       throw new DBUnexpectedError( $this, 'DatabaseBase::makeList called with incorrect parameters' );
+                       throw new DBUnexpectedError( $this, __METHOD__ . ' called with incorrect parameters' );
                }
 
                $first = true;
@@ -1879,7 +1823,6 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
         * @return string Full database name
         */
        public function tableName( $name, $format = 'quoted' ) {
-               global $wgSharedDB, $wgSharedPrefix, $wgSharedTables, $wgSharedSchema;
                # Skip the entire process when we have a string quoted on both ends.
                # Note that we check the end so that we will still quote any use of
                # use of `database`.table. But won't break things if someone wants
@@ -1916,14 +1859,14 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                        $schema = null;
                } else {
                        list( $table ) = $dbDetails;
-                       if ( $wgSharedDB !== null # We have a shared database
-                               && $this->mForeign == false # We're not working on a foreign database
-                               && !$this->isQuotedIdentifier( $table ) # Prevent shared tables listing '`table`'
-                               && in_array( $table, $wgSharedTables ) # A shared table is selected
-                       ) {
-                               $database = $wgSharedDB;
-                               $schema = $wgSharedSchema === null ? $this->mSchema : $wgSharedSchema;
-                               $prefix = $wgSharedPrefix === null ? $this->mTablePrefix : $wgSharedPrefix;
+                       if ( isset( $this->tableAliases[$table] ) ) {
+                               $database = $this->tableAliases[$table]['dbname'];
+                               $schema = is_string( $this->tableAliases[$table]['schema'] )
+                                       ? $this->tableAliases[$table]['schema']
+                                       : $this->mSchema;
+                               $prefix = is_string( $this->tableAliases[$table]['prefix'] )
+                                       ? $this->tableAliases[$table]['prefix']
+                                       : $this->mTablePrefix;
                        } else {
                                $database = null;
                                $schema = $this->mSchema; # Default schema
@@ -1934,7 +1877,9 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                # Quote $table and apply the prefix if not quoted.
                # $tableName might be empty if this is called from Database::replaceVars()
                $tableName = "{$prefix}{$table}";
-               if ( $format == 'quoted' && !$this->isQuotedIdentifier( $tableName ) && $tableName !== '' ) {
+               if ( $format == 'quoted'
+                       && !$this->isQuotedIdentifier( $tableName ) && $tableName !== ''
+               ) {
                        $tableName = $this->addIdentifierQuotes( $tableName );
                }
 
@@ -2417,8 +2362,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                $fname = __METHOD__
        ) {
                if ( !$conds ) {
-                       throw new DBUnexpectedError( $this,
-                               'DatabaseBase::deleteJoin() called with empty $conds' );
+                       throw new DBUnexpectedError( $this, __METHOD__ . ' called with empty $conds' );
                }
 
                $delTable = $this->tableName( $delTable );
@@ -2442,7 +2386,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
        public function textFieldSize( $table, $field ) {
                $table = $this->tableName( $table );
                $sql = "SHOW COLUMNS FROM $table LIKE \"$field\";";
-               $res = $this->query( $sql, 'DatabaseBase::textFieldSize' );
+               $res = $this->query( $sql, __METHOD__ );
                $row = $this->fetchObject( $res );
 
                $m = [];
@@ -2470,7 +2414,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
 
        public function delete( $table, $conds, $fname = __METHOD__ ) {
                if ( !$conds ) {
-                       throw new DBUnexpectedError( $this, 'DatabaseBase::delete() called with no conditions' );
+                       throw new DBUnexpectedError( $this, __METHOD__ . ' called with no conditions' );
                }
 
                $table = $this->tableName( $table );
@@ -2727,23 +2671,23 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                return false;
        }
 
-       final public function onTransactionResolution( callable $callback ) {
+       final public function onTransactionResolution( callable $callback, $fname = __METHOD__ ) {
                if ( !$this->mTrxLevel ) {
                        throw new DBUnexpectedError( $this, "No transaction is active." );
                }
-               $this->mTrxEndCallbacks[] = [ $callback, wfGetCaller() ];
+               $this->mTrxEndCallbacks[] = [ $callback, $fname ];
        }
 
-       final public function onTransactionIdle( callable $callback ) {
-               $this->mTrxIdleCallbacks[] = [ $callback, wfGetCaller() ];
+       final public function onTransactionIdle( callable $callback, $fname = __METHOD__ ) {
+               $this->mTrxIdleCallbacks[] = [ $callback, $fname ];
                if ( !$this->mTrxLevel ) {
                        $this->runOnTransactionIdleCallbacks( self::TRIGGER_IDLE );
                }
        }
 
-       final public function onTransactionPreCommitOrIdle( callable $callback ) {
+       final public function onTransactionPreCommitOrIdle( callable $callback, $fname = __METHOD__ ) {
                if ( $this->mTrxLevel ) {
-                       $this->mTrxPreCommitCallbacks[] = [ $callback, wfGetCaller() ];
+                       $this->mTrxPreCommitCallbacks[] = [ $callback, $fname ];
                } else {
                        // If no transaction is active, then make one for this callback
                        $this->startAtomic( __METHOD__ );
@@ -2759,7 +2703,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
 
        final public function setTransactionListener( $name, callable $callback = null ) {
                if ( $callback ) {
-                       $this->mTrxRecurringCallbacks[$name] = [ $callback, wfGetCaller() ];
+                       $this->mTrxRecurringCallbacks[$name] = $callback;
                } else {
                        unset( $this->mTrxRecurringCallbacks[$name] );
                }
@@ -2812,7 +2756,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                                                $this->clearFlag( DBO_TRX ); // restore auto-commit
                                        }
                                } catch ( Exception $ex ) {
-                                       MWExceptionHandler::logException( $ex );
+                                       call_user_func( $this->errorLogger, $ex );
                                        $e = $e ?: $ex;
                                        // Some callbacks may use startAtomic/endAtomic, so make sure
                                        // their transactions are ended so other callbacks don't fail
@@ -2846,7 +2790,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                                        list( $phpCallback ) = $callback;
                                        call_user_func( $phpCallback );
                                } catch ( Exception $ex ) {
-                                       MWExceptionHandler::logException( $ex );
+                                       call_user_func( $this->errorLogger, $ex );
                                        $e = $e ?: $ex;
                                }
                        }
@@ -2874,12 +2818,11 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                /** @var Exception $e */
                $e = null; // first exception
 
-               foreach ( $this->mTrxRecurringCallbacks as $callback ) {
+               foreach ( $this->mTrxRecurringCallbacks as $phpCallback ) {
                        try {
-                               list( $phpCallback ) = $callback;
                                $phpCallback( $trigger, $this );
                        } catch ( Exception $ex ) {
-                               MWExceptionHandler::logException( $ex );
+                               call_user_func( $this->errorLogger, $ex );
                                $e = $e ?: $ex;
                        }
                }
@@ -2943,15 +2886,13 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                        } else {
                                // @TODO: make this an exception at some point
                                $msg = "$fname: Implicit transaction already active (from {$this->mTrxFname}).";
-                               wfLogDBError( $msg );
-                               wfWarn( $msg );
+                               $this->queryLogger->error( $msg );
                                return; // join the main transaction set
                        }
                } elseif ( $this->getFlag( DBO_TRX ) && $mode !== self::TRANSACTION_INTERNAL ) {
                        // @TODO: make this an exception at some point
                        $msg = "$fname: Implicit transaction expected (DBO_TRX set).";
-                       wfLogDBError( $msg );
-                       wfWarn( $msg );
+                       $this->queryLogger->error( $msg );
                        return; // let any writes be in the main transaction
                }
 
@@ -2965,7 +2906,7 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                $this->mTrxAutomatic = ( $mode === self::TRANSACTION_INTERNAL );
                $this->mTrxAutomaticAtomic = false;
                $this->mTrxAtomicLevels = [];
-               $this->mTrxShortId = wfRandomString( 12 );
+               $this->mTrxShortId = sprintf( '%06x', mt_rand( 0, 0xffffff ) );
                $this->mTrxWriteDuration = 0.0;
                $this->mTrxWriteQueryCount = 0;
                $this->mTrxWriteAdjDuration = 0.0;
@@ -3010,13 +2951,12 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                        }
                } else {
                        if ( !$this->mTrxLevel ) {
-                               wfWarn( "$fname: No transaction to commit, something got out of sync." );
+                               $this->queryLogger->error( "$fname: No transaction to commit, something got out of sync." );
                                return; // nothing to do
                        } elseif ( $this->mTrxAutomatic ) {
                                // @TODO: make this an exception at some point
                                $msg = "$fname: Explicit commit of implicit transaction.";
-                               wfLogDBError( $msg );
-                               wfWarn( $msg );
+                               $this->queryLogger->error( $msg );
                                return; // wait for the main transaction set commit round
                        }
                }
@@ -3057,7 +2997,8 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                        }
                } else {
                        if ( !$this->mTrxLevel ) {
-                               wfWarn( "$fname: No transaction to rollback, something got out of sync." );
+                               $this->queryLogger->error(
+                                       "$fname: No transaction to rollback, something got out of sync." );
                                return; // nothing to do
                        } elseif ( $this->getFlag( DBO_TRX ) ) {
                                throw new DBUnexpectedError(
@@ -3126,18 +3067,17 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
         * @param string $newName Name of table to be created
         * @param bool $temporary Whether the new table should be temporary
         * @param string $fname Calling function name
-        * @throws MWException
+        * @throws RuntimeException
         * @return bool True if operation was successful
         */
        public function duplicateTableStructure( $oldName, $newName, $temporary = false,
                $fname = __METHOD__
        ) {
-               throw new RuntimeException(
-                       'DatabaseBase::duplicateTableStructure is not implemented in descendant class' );
+               throw new RuntimeException( __METHOD__ . ' is not implemented in descendant class' );
        }
 
        function listTables( $prefix = null, $fname = __METHOD__ ) {
-               throw new RuntimeException( 'DatabaseBase::listTables is not implemented in descendant class' );
+               throw new RuntimeException( __METHOD__ . ' is not implemented in descendant class' );
        }
 
        /**
@@ -3156,24 +3096,24 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
         *
         * @param string $prefix Only show VIEWs with this prefix, eg. unit_test_
         * @param string $fname Name of calling function
-        * @throws MWException
+        * @throws RuntimeException
         * @return array
         * @since 1.22
         */
        public function listViews( $prefix = null, $fname = __METHOD__ ) {
-               throw new RuntimeException( 'DatabaseBase::listViews is not implemented in descendant class' );
+               throw new RuntimeException( __METHOD__ . ' is not implemented in descendant class' );
        }
 
        /**
         * Differentiates between a TABLE and a VIEW
         *
         * @param string $name Name of the database-structure to test.
-        * @throws MWException
+        * @throws RuntimeException
         * @return bool
         * @since 1.22
         */
        public function isView( $name ) {
-               throw new RuntimeException( 'DatabaseBase::isView is not implemented in descendant class' );
+               throw new RuntimeException( __METHOD__ . ' is not implemented in descendant class' );
        }
 
        public function timestamp( $ts = 0 ) {
@@ -3357,8 +3297,8 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
         *   generated dynamically using $filename
         * @param bool|callable $inputCallback Optional function called for each
         *   complete line sent
-        * @throws Exception|MWException
         * @return bool|string
+        * @throws Exception
         */
        public function sourceFile(
                $filename, $lineCallback = false, $resultCallback = false, $fname = false, $inputCallback = false
@@ -3387,25 +3327,6 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                return $error;
        }
 
-       /**
-        * Get the full path of a patch file. Originally based on archive()
-        * from updaters.inc. Keep in mind this always returns a patch, as
-        * it fails back to MySQL if no DB-specific patch can be found
-        *
-        * @param string $patch The name of the patch, like patch-something.sql
-        * @return string Full path to patch file
-        */
-       public function patchPath( $patch ) {
-               global $IP;
-
-               $dbType = $this->getType();
-               if ( file_exists( "$IP/maintenance/$dbType/archives/$patch" ) ) {
-                       return "$IP/maintenance/$dbType/archives/$patch";
-               } else {
-                       return "$IP/maintenance/archives/$patch";
-               }
-       }
-
        public function setSchemaVars( $vars ) {
                $this->mSchemaVars = $vars;
        }
@@ -3605,15 +3526,18 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                                // There is a good chance an exception was thrown, causing any early return
                                // from the caller. Let any error handler get a chance to issue rollback().
                                // If there isn't one, let the error bubble up and trigger server-side rollback.
-                               $this->onTransactionResolution( function () use ( $lockKey, $fname ) {
-                                       $this->unlock( $lockKey, $fname );
-                               } );
+                               $this->onTransactionResolution(
+                                       function () use ( $lockKey, $fname ) {
+                                               $this->unlock( $lockKey, $fname );
+                                       },
+                                       $fname
+                               );
                        } else {
                                $this->unlock( $lockKey, $fname );
                        }
                } );
 
-               $this->commit( __METHOD__, self::FLUSHING_INTERNAL );
+               $this->commit( $fname, self::FLUSHING_INTERNAL );
 
                return $unlocker;
        }
@@ -3707,6 +3631,10 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface {
                return is_string( $reason ) ? $reason : false;
        }
 
+       public function setTableAliases( array $aliases ) {
+               $this->tableAliases = $aliases;
+       }
+
        /**
         * @since 1.19
         * @return string